/**
 * 统计修复程序
 * */
package cn.antia.cep.report;

import cn.antia.cep.busi.*;
import cn.antia.cwin.db.DbService;

public class VisitRepair {
	private DbService dbService;
	private DbHibernateService dbHibernateService;
	
	public DbHibernateService getDbHibernateService() {
		return dbHibernateService;
	}
	public void setDbHibernateService(DbHibernateService dbHibernateService) {
		this.dbHibernateService = dbHibernateService;
	}
	public DbService getDbService() {
		return dbService;
	}
	public void setDbService(DbService dbService) {
		this.dbService = dbService;
	}

	/**
	 * 重新统计日仿问统计和月仿问统计
     *
     * @throws cn.antia.cep.common.AntiaException e
     * */
	/*
	public void repairVisitStatAll() throws AntiaException {
		List allLog = dbHibernateService.find("select new VisitLog(id,userType,loginType,loginTime,activeTime,ip,clickTimes,learnsLoginTime,learnsUsageTime) from VisitLog order by id asc");
		AntiaLog.debug("visit log has total " + allLog.size() + " record");
		VisitLog startLog = (VisitLog) allLog.get(0);
		VisitLog endLog = (VisitLog) allLog.get(allLog.size() - 1);
		Date startDate = startLog.getLoginTime();
		Date endDate = endLog.getLoginTime();
		// 开始日期
		Calendar cstart = Calendar.getInstance();
		cstart.setTime(startDate);
		// 结束日期
		Calendar cend = Calendar.getInstance();
		cend.setTime(endDate);
		// 开始的 年/月/日
		int startYear = cstart.get(Calendar.YEAR);
		int startMonth = cstart.get(Calendar.MONTH) + 1;
		int startDay = cstart.get(Calendar.DAY_OF_MONTH);
		// 结束的年/月/日
		int endYear = cend.get(Calendar.YEAR);
		int endMonth = cend.get(Calendar.MONTH) + 1;
		int endDay = cend.get(Calendar.DAY_OF_MONTH);
		System.out.println(cend);
		// 取开始日的一天开始 比如 2007-5-1 00:00:00
		String sstart = new StringBuffer().append(startYear).append("-").append(
				startMonth).append("-").append(startDay).toString();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date ccstart;
        try{
            ccstart = format.parse(sstart);
        }catch(Exception e){
            AntiaLog.error("parse date error..");
            return;
        }
        long lcstart = ccstart.getTime();
		// 取结束日的天天开始 比如 2007-7-18 00:00:00
		String send = new StringBuffer().append(endYear).append("-").append(endMonth).append("-").append(endDay).toString();
        Date ccend;
        try{
            ccend = format.parse(send);
        }catch(Exception e){
            AntiaLog.error("parse date error..");
            return;
        }
        long lcend = ccend.getTime();
		// 按两小时循环处理
		long temp1, temp2;
		Calendar ctemp = Calendar.getInstance();
		VisitLog logTemp;
		// 按天循环
		int i = 0;
		List dayStas = new ArrayList();
		List hourStats = new ArrayList();
		//按每两小时循环/按两小时统计
		for (; lcstart < lcend;) {
			temp1 = lcstart;
			lcstart += 7200000;
			temp2 = lcstart;
			//时间
			ctemp.setTimeInMillis(temp1);
			int y = ctemp.get(Calendar.YEAR);
			int m = ctemp.get(Calendar.MONTH) + 1;
			int d = ctemp.get(Calendar.DAY_OF_MONTH);
			int h = ctemp.get(Calendar.HOUR_OF_DAY);
			h = h / 2 + 1;
			// 统计变量
			int cactiveTime = 0; // 活动时间
			int csessionCount = 0; // SESSION个数
			int cclickTimes = 0; // 点击量
			int cloginTimes = 0; // 会员登录次数
			int cloginActiveTimes = 0; // 会员活动时间
			int cloginClickTimes = 0;	//会员点击次数
			int clearnsLoginTimes = 0; // 学习系统登录次数
			int clearnsActiveTimes = 0; // 学习系统使用时间
			// 查找所以日志
			for (int j = i; j < allLog.size(); j++, i++) {
				logTemp = (VisitLog) allLog.get(j);
				if(logTemp.getLoginTime().getTime() > temp2){
					break;
				}
				long ltemp = logTemp.getLoginTime().getTime();
				if (ltemp <= temp2 && ltemp > temp1) {
					csessionCount++;
					if(logTemp.getActiveTime() != null){
						cactiveTime += Integer.parseInt(logTemp.getActiveTime());
					}
					if(logTemp.getClickTimes() != null){
						cclickTimes += logTemp.getClickTimes().intValue();
					}
					// 如果是会员登录，则设置会员使用情况
					if (logTemp.getUserType().intValue() == DBFlag.VISIT_LOG_USER_REGISTERED && logTemp.getActiveTime() != null) {
						cloginTimes++;
						cloginActiveTimes += Integer.parseInt(logTemp.getActiveTime());
						cloginClickTimes += logTemp.getClickTimes().intValue();
					}
					// 如果使用过学习系统，则统计学习系统数据
					if (logTemp.getLearnsLoginTime() != null && logTemp.getLearnsUsageTime() != null) {
						clearnsLoginTimes++;
						clearnsActiveTimes += logTemp.getLearnsUsageTime().intValue();
					}
				}
			}
			VisitStat stat = new VisitStat();
			stat.setSessionCount(new Integer(csessionCount));
			stat.setAtimeCount(new Integer(cactiveTime));
			stat.setCtimesCount(new Integer(cclickTimes));
			// 学习系统信息统计
			stat.setLearnsAtimeCount(new Integer(clearnsActiveTimes));
			stat.setLearnsLoginCount(new Integer(clearnsLoginTimes));
			// 注册用户登录统计
			stat.setMemberAtimeCount(new Integer(cloginActiveTimes));
			stat.setMemberLoginTimes(new Integer(cloginTimes));
			stat.setMemberClickTimes(new Integer(cloginClickTimes));
			// 统计类型
			stat.setStatType(new Integer(ReportConst.VISIT_2HOUR));
			// 计算统计标志 xxxx xx xx 前四位为 年，中间两位为 月 后两位为 日
			stat.setStatFlag(new Integer(y * 1000000 + m * 10000 + d * 100 + h));
			// 加入列表
			hourStats.add(stat);
			//检查是否已经到了一天或一个月的终点
			ctemp.setTimeInMillis(temp2);
			//如果下两个小时已经是下一天，那么处理现有的小时统计数据
			if(d != ctemp.get(Calendar.DAY_OF_MONTH)){
				VisitStat stat2 = statWithDetail(hourStats,1);
				dayStas.add(stat2);
				hourStats = new ArrayList();
			}
			//如果下两个小时已经是下一个月，那么处理现有的日统计数据
			if(ctemp.get(Calendar.MONTH) + 1 != m){
				//统计月数据并保存
				statWithDetail(dayStas,2);
				//重置日统计列表
				dayStas = new ArrayList();
			}
		}
		//如果最后一天还有几个小时的数据没有保存，检查现在的所在的小时段是否也被统计，如果是，就删除当前时间段的数据
		Calendar c = Calendar.getInstance();
		int y = c.get(Calendar.YEAR);
		int m = c.get(Calendar.MONTH) + 1;
		int d = c.get(Calendar.DAY_OF_MONTH);
		int h = c.get(Calendar.HOUR_OF_DAY);
		h = h / 2 + 1;
		if(hourStats.size() > 0){
			VisitStat stat = (VisitStat)hourStats.get(hourStats.size() -1);
			int flag = y * 1000000 + m * 10000 + d * 100 + h;
			if(stat.getStatFlag().intValue() == flag){
				hourStats.remove(stat);
			}
			if(hourStats.size() > 0){
				statWithDetail(hourStats,1);
			}
		}
		//如果最后一个月还有些天的数据没有保存，检查当前天的数据是否也被统计，如果是，就删除当前天的统计数据
		if(dayStas.size() > 0){
			VisitStat stat = (VisitStat)dayStas.get(dayStas.size() -1);
			int flag = y * 10000 + m * 100 + d;
			if(stat.getStatFlag().intValue() == flag){
				dayStas.remove(dayStas.size() - 1);
			}
			if(dayStas.size() > 0){
				statWithDetail(dayStas,3);
			}
		}
	}

	/**
	 * 修复小时统计
	 * @param hour 小时/时段 1 ~ 12，代表 24 个小时
	 * @throws cn.antia.cep.common.AntiaException e
     * *//*
	public void repairVisitStatHour(int hour) throws AntiaException{
		String where = " stat_flag > 1000000000 and mod(stat_flag,100) = " + hour;
		VisitStat stat = new VisitStat();
		stat.setStatFlag(new Integer(hour));
		stat.setStatType(new Integer(ReportConst.VISIT_CATE_HOUR));
		//修复
		repairStat(where, stat);
	}
	/**
	 * 修复月统计
	 * @param year 年
	 * @param month 月
	 * 
	 * @throws cn.antia.cep.common.AntiaException e*//*
	public void repairVisitStatMonth(int year,int month)throws AntiaException{
		int startFlag = year * 10000 + month * 100;
		int endFlag = startFlag + 32;
		VisitStat stat = new VisitStat();
		stat.setStatFlag(new Integer(startFlag / 100));
		stat.setStatType(new Integer(ReportConst.VISIT_MONTH));
		//统计条件
		String where = new StringBuffer(" stat_type >= ").append(startFlag).append(" and stat_type <= ").append(endFlag).toString();
		//修复
		repairStat(where, stat);
	}

	// 修复日期统计
	/**
	 * 修复日统计
	 * @param year 年
	 * @param month 月
	 * @param day 日
	 * 
	 * @throws cn.antia.cep.common.AntiaException e*//*
	public void repairVisitStatDay(int year, int month, int day) throws AntiaException{
		int startFlag = year * 1000000 + month * 10000 + day * 100;
		int endFlag = startFlag + 12;
		VisitStat stat = new VisitStat();
		stat.setStatFlag(new Integer(startFlag / 100));
		stat.setStatType(new Integer(ReportConst.VISIT_DAY));
		//统计条件
		String where = new StringBuffer(" stat_type >= ").append(startFlag).append(" and stat_type <= ").append(endFlag).toString();
		//修复
		repairStat(where, stat);
	}
	/**
	 * 修复每天的分小时仿问统计数据，但需要指定时间
	 * @param year 年
	 * @param month 月
	 * @param day 日
	 * @param hour 时 ( 1 ~ 12)
	 * @exception AntiaException ..通用异常
	 * *//*
	public void repairVisitStatDayHour(int year,int month,int day,int hour)throws AntiaException{
		int sh = hour * 2 - 2;
		int eh = sh + 2;
		String sdateString = new StringBuffer().append(year).append("-").append(month).append("-").append(day).append(" ").append(sh).append(":00:00").toString();
		String edateString;
		//如果是一天的最后一次统计，则比较日期时结束日期应是第二天
		if(eh == 24){
			SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
			String sdate = year * 10000 + month * 100 + day + "";
			Date date;
			try{
				date = format.parse(sdate);
			}catch(Exception e){
				e.printStackTrace();
                AntiaLog.error(new StringBuffer().append("解析日期出错，没有修复").append(sdateString).append("的统计数据。").toString());
                return;
            }
			Calendar calendar = Calendar.getInstance();
			//当时时间加一天
			calendar.setTimeInMillis(date.getTime() + 86400000);
			int y = calendar.get(Calendar.YEAR);
			int m = calendar.get(Calendar.MONTH + 1);
			int d = calendar.get(Calendar.DAY_OF_MONTH);
			edateString = new StringBuffer().append(y).append("-").append(m).append("-").append(d).append(" 00:00:00").toString();
		}else{
			edateString = new StringBuffer().append(year).append("-").append(month).append("-").append(day).append(" ").append(eh).append(":00:00").toString();
		}
		//查询总的统计
		String where = new StringBuffer(" login_time > '").append(sdateString).append("' and login_time < '").append(edateString).append("'").toString();
		String sql = "select count(*) scount,sum(active_time) sat,sum(click_times) sct,sum(learns_usage_time) slut from visit_log where" + where;
		List list = dbService.find(sql);
		//小时统计
		VisitStat stat = new VisitStat();
		int flag = year * 1000000 + month * 10000 + day * 100 + hour;
		stat.setStatFlag(new Integer(flag));
		stat.setStatType(new Integer(ReportConst.VISIT_2HOUR));
		for(int i = 0;i<list.size();i++){
			List list2 = (List)list.get(0);
			for(int j = 0;j<list2.size();j++){
				Cele comsat = (Cele)list2.get(j);
				String value = comsat.getValue() == null ? "0" : comsat.getValue();
				if(comsat.getFieldName().equals("scount")){
					stat.setSessionCount(new Integer(value));
				}else if(comsat.getFieldName().equals("sct")){
					stat.setCtimesCount(new Integer(value));
				}else if(comsat.getFieldName().equals("slut")){
					stat.setLearnsAtimeCount(new Integer(value));
				}else if(comsat.getFieldName().equals("sat")){
					stat.setAtimeCount(new Integer(value));
				}
			}
		}
		
		sql = "select count(*) login_user,sum(click_times) sct,sum(active_time) sat from visit_log where user_type = 1 and " + where;
		list = dbService.find(sql);
		List list2 = (List)list.get(0);
		for(int j = 0;j<list2.size();j++){
			Cele comsat = (Cele)list2.get(j);
			String value = comsat.getValue() == null ? "0" : comsat.getValue();
			Integer v = new Integer(value);
			if(comsat.getFieldName().equals("login_user")){
				stat.setMemberLoginTimes(v);
			}else if(comsat.getFieldName().equals("sct")){
				stat.setMemberClickTimes(v);
			}else if(comsat.getFieldName().equals("sat")){
				stat.setMemberAtimeCount(v);
			}
		}
		sql = "select count(*) sc from visit_log where learns_login_time <> null and " + where;
		list = dbService.find(sql);
		list2 = (List)list.get(0);
		Cele comsat = (Cele)list2.get(0);
		stat.setLearnsLoginCount(new Integer(comsat.getValue()));
		dbHibernateService.addEntity(stat);
	}
	
	/**
	 * 修复周统计
	 * @param week 周几 值从 1~7，分别代表 星期日 ~ 星期六
	 * @return VisitStat
     * @throws cn.antia.cep.common.AntiaException e*//*
	public VisitStat repairVisitStatWeek(int week) throws AntiaException{
		VisitStat stat = new VisitStat();
		stat.setStatType(new Integer(ReportConst.VISIT_CATE_WEEK));
		stat.setStatFlag(new Integer(week));
		List stats = dbHibernateService.findEntity(stat, true);
		if(stats != null && stats.size() == 1){
			stat = (VisitStat)stats.get(0);
		}else{
			dbHibernateService.deleteEntity(stat);
		}
		String hql = "from VisitStat where statType = " + ReportConst.VISIT_DAY;
		List allStat = dbHibernateService.find(hql);
		VisitStat visitStat;
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
		Date date;
		Calendar calendar = Calendar.getInstance();
		//统计变量
		int cactiveTime = 0; // 活动时间
		int csessionCount = 0; // SESSION个数
		int cclickTimes = 0; // 点击量
		int cloginTimes = 0; // 会员登录次数
		int cloginActiveTimes = 0; // 会员活动时间
		int cloginClickTimes = 0;	//会员点击次数
		int clearnsLoginTimes = 0; // 学习系统登录次数
		int clearnsActiveTimes = 0; // 学习系统使用时间
		try{
			for(int i = 0;i<allStat.size();i++){
				visitStat = (VisitStat)allStat.get(i);
				String sdate = visitStat.getStatFlag().intValue() + "";
				date = dateFormat.parse(sdate);
				calendar.setTime(date);
				if(calendar.get(Calendar.DAY_OF_WEEK) == week){
					cactiveTime += (visitStat.getAtimeCount() == null ? 0 : visitStat.getAtimeCount().intValue());
					csessionCount += (visitStat.getSessionCount() == null ? 0 : visitStat.getSessionCount().intValue());
					cclickTimes += (visitStat.getCtimesCount() == null ? 0 : visitStat.getCtimesCount().intValue());
					cloginTimes += (visitStat.getMemberLoginTimes() == null ? 0 : visitStat.getMemberLoginTimes().intValue());
					cloginActiveTimes += (visitStat.getMemberAtimeCount() == null ? 0 : visitStat.getMemberAtimeCount().intValue());
					cloginClickTimes += (visitStat.getMemberClickTimes() == null ? 0 : visitStat.getMemberClickTimes().intValue());
					clearnsLoginTimes += (visitStat.getLearnsLoginCount() == null ? 0 : visitStat.getLearnsLoginCount().intValue());
					clearnsActiveTimes += (visitStat.getLearnsAtimeCount() == null ? 0 : visitStat.getLearnsAtimeCount().intValue());
				}
			}
		}catch(Exception e){
			AntiaLog.error("修复周统计时出现异常。");
			e.printStackTrace();
		}
		stat.setSessionCount(new Integer(csessionCount));
		stat.setAtimeCount(new Integer(cactiveTime));
		stat.setCtimesCount(new Integer(cclickTimes));
		// 学习系统信息统计
		stat.setLearnsAtimeCount(new Integer(clearnsActiveTimes));
		stat.setLearnsLoginCount(new Integer(clearnsLoginTimes));
		// 注册用户登录统计
		stat.setMemberAtimeCount(new Integer(cloginActiveTimes));
		stat.setMemberLoginTimes(new Integer(cloginTimes));
		stat.setMemberClickTimes(new Integer(cloginClickTimes));
		if(stat.getId() == null){
			dbHibernateService.addEntity(stat);
		}else{
			dbHibernateService.updateEntity(stat);
		}
		return stat;
	}
	
	/**
	 * 给定一个列表的统计数据，记录这些数据并计算这个列表的最终数据
	 * 如果统计的是日数据，不保存统计后的结果到数据库，而是仅仅返回
	 * @param stats 统计对象列表
	 * @param flag 标志：取值为1和2各3，如果是1，则表示日数据统计，如果是2，则表示月数据统计，如果是3，表示月统计，
	 * 但不做月统计，只保存日数据
     * @return VisitStat
     * @throws cn.antia.cep.common.AntiaException e
	 *//*
	private VisitStat statWithDetail(List stats,int flag) throws AntiaException {
		VisitStat stat = new VisitStat();
		VisitStat temp;
		// 统计变量
		int cactiveTime = 0; // 活动时间
		int csessionCount = 0; // SESSION个数
		int cclickTimes = 0; // 点击量
		int cloginTimes = 0; // 会员登录次数
		int cloginActiveTimes = 0; // 会员活动时间
		int clearnsLoginTimes = 0; // 学习系统登录次数
		int clearnsActiveTimes = 0; // 学习系统使用时间
		// 统计标志
		int statFlag = 0;
		for (int i = 0; i < stats.size(); i++) {
			temp = (VisitStat) stats.get(i);
			if (i == 0) {
				statFlag = temp.getStatFlag().intValue() / 100;
			}
			cactiveTime += temp.getAtimeCount().intValue();
			csessionCount+= temp.getSessionCount().intValue();
			cclickTimes += temp.getCtimesCount().intValue();
			// 如果是会员登录，则设置会员使用情况
			if (temp.getMemberLoginTimes() != null) {
				cloginTimes += temp.getMemberLoginTimes().intValue();
				cloginActiveTimes += temp.getMemberAtimeCount().intValue();
			}
			// 如果使用过学习系统，则统计学习系统数据
			if (temp.getLearnsLoginCount() != null) {
				clearnsLoginTimes += temp.getLearnsLoginCount().intValue();
				clearnsActiveTimes += temp.getLearnsAtimeCount().intValue();
			}
		}
		stat.setSessionCount(new Integer(csessionCount));
		stat.setAtimeCount(new Integer(cactiveTime));
		stat.setCtimesCount(new Integer(cclickTimes));
		// 学习系统信息统计
		stat.setLearnsAtimeCount(new Integer(clearnsActiveTimes));
		stat.setLearnsLoginCount(new Integer(clearnsLoginTimes));
		// 注册用户登录统计
		stat.setMemberAtimeCount(new Integer(cloginActiveTimes));
		stat.setMemberLoginTimes(new Integer(cloginTimes));
		//如果是统计日数据
		if(flag == 1){
			stat.setStatType(new Integer(ReportConst.VISIT_DAY));
			stat.setStatFlag(new Integer(statFlag));
		}else if(flag == 2 || flag == 3){
			//统计月数据
			// 统计类型
			stat.setStatType(new Integer(ReportConst.VISIT_MONTH));
			stat.setStatFlag(new Integer(statFlag));
			//保存月统计数据
			if(flag == 2){
				dbHibernateService.addEntity(stat);
			}
		}
		//保存零散统计数据
		dbHibernateService.addEntityList(stats);
		return stat;
	}
	
	/**
	 * 修复
	 * @param where 统计条件(查询条件)
	 * @param stat 统计对象，存储了统计类型和统计标志
	 * @return VisitStat
     * @throws cn.antia.cep.common.AntiaException e*//*
	private VisitStat repairStat(String where,VisitStat stat)throws AntiaException{
		List list = dbHibernateService.findEntity(stat, true);
		String sql = "select sum(session_count) scount,sum(ctimes_count) scc,sum(atime_count) sac,sum(learns_login_count) sllc,sum(learns_atime_count) slac,sum(member_login_times) smlt,sum(member_atime_count) smac,sum(member_click_times) smct from visit_stat where " + where;
		List stats = dbService.find(sql);
		if(stats != null && stats.size() == 1){
			stat = (VisitStat)stats.get(0);
		}else if(stats != null && stats.size() > 1){
			//如果有两条以上的晶统计数据。。删除，重新统计
			dbHibernateService.deleteEntity(stat);
		}
		List list1 = (List)list.get(0);
		Cele comsat;
		for(int i = 0;i<list1.size();i++){
			comsat = (Cele)list1.get(i);
			String fieldName = comsat.getFieldName();
			String value = comsat.getValue() == null ? "0" : comsat.getValue();
			if(fieldName.equals("scount")){
				stat.setSessionCount(new Integer(value));
			}else if(fieldName.equals("scc")){
				stat.setCtimesCount(new Integer(value));
			}else if(fieldName.equals("sac")){
				stat.setAtimeCount(new Integer(value));
			}else if(fieldName.equals("sllc")){
				stat.setLearnsLoginCount(new Integer(value));
			}else if(fieldName.equals("slac")){
				stat.setLearnsAtimeCount(new Integer(value));
			}else if(fieldName.equals("smlt")){
				stat.setMemberLoginTimes(new Integer(value));
			}else if(fieldName.equals("smac")){
				stat.setMemberAtimeCount(new Integer(value));
			}else if(fieldName.equals("smct")){
				stat.setMemberClickTimes(new Integer(value));
			}
		}
		if(stat.getId() == null){
			dbHibernateService.addEntity(stat);
		}else{
			dbHibernateService.updateEntity(stat);
		}
		return stat;
	}*/
}
